Skip to content

Bandwidth control#147

Merged
vDorst merged 3 commits intomainfrom
bandwidth
Mar 8, 2026
Merged

Bandwidth control#147
vDorst merged 3 commits intomainfrom
bandwidth

Conversation

@logicog
Copy link
Owner

@logicog logicog commented Mar 2, 2026

Add a bandwidth control mechanism for ingress and egress at a given port.

The documentation contains an example making use of this feature using loopback on a Linux device through an external RTL-switch. Applications of the feature include configuring bandwidth shares of e.g. an uplink connection and the simulation of low bandwidth connections with or without packet drops.

@logicog logicog requested review from feelfree69 and vDorst March 2, 2026 06:44
sfr_data[3] = (*(bwptr) >> 4) | (*(bwptr + 1) << 4);
reg_write_m(RTL837X_IGBW_PORT_CTRL + port * 4);

// We enable Flow Control instead of just dropping packets
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this as a configuration option. Usually, enabling Flow Control is a bad idea.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is configurable, you can change it to dropping the packets instead via bandwidth_ingress_drop(). While indeed FC is not great and depends on the support by the linkpartner, it is much better than the alternative, namely to drop the packets, see the examples in the documentation: bandwidth.md. As can be seen, the traffic is no longer deterministic because of packets being dropped arbitrarily in the middle of the configuration causing TCP back-off to trigger. Using Flow Control, the data stream shows reliably the desired bitrate without any dropped packets. So I prefer making FC the default in order to not surprise the user with bitrates that are erratic.


To drop packets when the bandwidth is exceeeded at port 2 do:
```
> bw in 2 drop
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the way back, i.e. to enable FLowControl again?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is maybe a misunderstanding. The bandwidth control does not enable or disable FlowControl. FC is a PHY feature, here we are talking about scheduling even before the MAC layer. The bandwidth control merely uses FC or not. It is not enabling or disabling it. This would require to configure the PHY. I verified it using sudo ip netns exec client ethtool -a : if you disable the use of FC, it still is configured and enabled on the link, even if no longer used. It is even used during transmission, it is just not used when the bandwidth is exceeded to lower throughput.

So drop explicitly stops usage of FC. To enable it again, one can again use bw in 1 1000.

Do you want an explicit command/function to enabled/disable use of FC?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want an explicit command/function to enabled/disable use of FC?

Yes, see my comment on bandwidth_ingress_set. There you implicitly switch FC on
And you have a command to switch FC off (ie to drop packets), but no command to switch FC back on, other than setting the bandwidth limit again.
While the config in SoC in regards of ingress bandwidth and FC is perfectly separated, the console commands are not. That looks as a bad design to me.

To enable bandwidth control of ingress for physical port 2 to be set to 256 Kbit/s
do:
```
> bw in 2 0100
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implictly enables flow control, which does work only if the link partner enables it too at its RX side.

I would make the FlowControl feature configurable explicitly.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is a misunderstanding, see above. FC is neither enabled nor disabled. This would not be possible at this level. FC stays on all the time even if not used. BTW: by default it is enabled and used if the link partner enables it. There is no way currently to configure it at the link level. The idea is that like EEE if it works it is good, if not, there is nothing much you can do. So we keep the default for all involved PHYs, which enables it by default.

Configures or shows the status of bandwidth control
```
The bandwidth is given as the `<hexvalue>` in Kbit/s. Note that the control is only
possible at a granularity of 16 Kbit/s and the minimum value is also 16 Kbit/s. The
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's ok at the console to have this granularity of what the chip supports and the unintuitive way of using hex values.
When adding this feature to the Web-Interface, I would expect eg a list of dedicated values, eg. from 16 kbit/s to 10 Gbit/s in steps of factor 2 or 4.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! In the web-interface configuring and verifying the settings is much easier. I have already a skeleton for the web-page but wanted the basics to be done, first.

@logicog
Copy link
Owner Author

logicog commented Mar 3, 2026

I added the possibility to revert to flow control for bandwidth management via bw in <port> fc. Also the drop option had been somehow dropped from the previous commit to the PR, so that code has been restored.


To drop packets when the bandwidth is exceeeded at port 2 do:
```
> bw in 2 drop
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want an explicit command/function to enabled/disable use of FC?

Yes, see my comment on bandwidth_ingress_set. There you implicitly switch FC on
And you have a command to switch FC off (ie to drop packets), but no command to switch FC back on, other than setting the bandwidth limit again.
While the config in SoC in regards of ingress bandwidth and FC is perfectly separated, the console commands are not. That looks as a bad design to me.

@logicog
Copy link
Owner Author

logicog commented Mar 3, 2026

I added the FC re-enable command and function and rebased.

@logicog logicog mentioned this pull request Mar 4, 2026
Copy link
Collaborator

@vDorst vDorst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all bw commands are working.

@logicog
Copy link
Owner Author

logicog commented Mar 5, 2026

I fixed all of the above and re-based to latest main.

cmd_parser.c Outdated

port = machine.phys_to_log_port[port];

if (cmd_words_b[1] > 0 && cmd_compare(1, "status")) {
Copy link
Collaborator

@vDorst vDorst Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we change (cmd_words_b[3] < 0) on L706.
Then cmd_words_b[1] > 0 is always true?
So need we still need to check this?

Same as below (cmd_words_b[3] > 0) is that also always true?

@logicog
Copy link
Owner Author

logicog commented Mar 7, 2026

I fixed the issue with the redundant checking of the number of present arguments in the command. The logic is now: check for 2 arguments for the status command, then require 3 arguments for all the other commands and no more checking for argument presence in any of the further command argument comparisons.

@vDorst
Copy link
Collaborator

vDorst commented Mar 8, 2026

I finally setup everything so I can test it for real.

tested SFP to SFP @ 10Gbit.

value 800000 result into

[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  5.93 GBytes  5.09 Gbits/sec  49540            sender
[  5]   0.00-10.00  sec  5.93 GBytes  5.09 Gbits/sec                  receiver

value 10000000 seems not working

> bw in 6 10000000
bandwidth_ingress_set called, port 03

> bw status 6
ingress: enabled: 0x00000000
egress: disabled

Setup value 800000 shows 80000 in the status.
That seems strange.

> bw in 6 800000
bandwidth_ingress_set called, port 03

> bw status 6
ingress: enabled: 0x00080000
egress: disabled

@logicog
Copy link
Owner Author

logicog commented Mar 8, 2026

Setup value 800000 shows 80000 in the status. That seems strange.


I think there is a bug, it should be one 0 more. The register content is in units 16KByte. I forgot to shift it correctly. But maybe I just append a 0.

@logicog
Copy link
Owner Author

logicog commented Mar 8, 2026

Can you try again?

@vDorst
Copy link
Collaborator

vDorst commented Mar 8, 2026

> bw in 6 800000
bandwidth_ingress_set called, port 03

> bw status 6
ingress: enabled: 0x0800000
egress: disabled

with the setting set as above
iperf results

[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  6.17 GBytes  5.30 Gbits/sec  56097            sender
[  5]   0.00-10.00  sec  6.17 GBytes  5.30 Gbits/sec                  receiver

is the value correct?
0x800000 = 3032400
3032400 x 16 Kbit/s = 40518400 Kbit/s = 47381 MBit = 47 Gbit.
So that seems off by around 10x.

@logicog
Copy link
Owner Author

logicog commented Mar 8, 2026 via email

@logicog
Copy link
Owner Author

logicog commented Mar 8, 2026 via email

@vDorst vDorst merged commit 87c161d into main Mar 8, 2026
1 check passed
@vDorst
Copy link
Collaborator

vDorst commented Mar 8, 2026

ah that explains it.
Thanks for the work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants